from selenium.webdriver import Chrome, \
    ChromeOptions, Firefox, FirefoxOptions, \
    FirefoxProfile, Ie, IeOptions
from ppts.entity.PagePerformanceData import PagePerformanceData
from ppts.core.TestUtil import execute_script
import logging
import time


# 初始化webDriver对象，传入参数,返回webDriver对象
def init_web_driver(browser_type='chrome', driver_path=None, no_headless=False, cache=False, timeout=30
                    , user_agent=None, cookie_list=[], browser_path=None):
    driver = None
    if browser_type == "ie":
        options = IeOptions()
        executable_path = 'IEDriverServer.exe'
        if driver_path:
            executable_path = driver_path
        driver = Ie(executable_path=executable_path, options=options)
        if not cache:
            driver.delete_all_cookies()
    elif browser_type == 'firefox':
        profile = FirefoxProfile()
        profile.accept_untrusted_certs = True
        options = FirefoxOptions()
        executable_path = 'geckodriver'
        # 如果配置了 headless 模式
        if no_headless:
            options.add_argument('-headless')
            options.add_argument('--disable-gpu')
            options.add_argument("--no-sandbox")
            options.add_argument('window-size=1920x1080')
        if user_agent:
            options.add_argument(f'User-Agent={user_agent}')  # 配置为自己设置的UA
        if driver_path:
            executable_path = driver_path
        driver = Firefox(firefox_profile=profile, executable_path=executable_path,
                         options=options)
        driver.maximize_window()
        if not cache:
            driver.delete_all_cookies()
            driver.find_element_by_xpath()
    elif browser_type == 'chrome':
        options = ChromeOptions()
        executable_path = 'chromedriver'
        # 如果配置了 headless 模式
        if no_headless:
            options.add_argument('--headless')
            options.add_argument('--disable-gpu')
            options.add_argument("--no-sandbox")
            options.add_argument('window-size=1920x1080')
        if user_agent:
            options.add_argument(f'User-Agent={user_agent}')  # 配置为自己设置的UA
        options.add_argument("--start-maximized")
        options.add_argument('--ignore-certificate-errors')
        # 指定浏览器分辨率，当"--start-maximized"无效时使用
        # options.add_argument('window-size=1920x1080')
        prefs = {
            "credentials_enable_service": False,
            "profile.password_manager_enabled": False
        }
        options.add_experimental_option("prefs", prefs)
        options.add_argument('disable-infobars')
        options.add_experimental_option("excludeSwitches", ['load-extension', 'enable-automation'])
        if driver_path:
            executable_path = driver_path
        if browser_path:
            options.binary_location = browser_path
        driver = Chrome(executable_path=executable_path, options=options)
        if not cache:
            driver.delete_all_cookies()
    else:
        raise Exception('不支持“%s”浏览器类型，请重新配置后再次执行！' % browser_type)
    # 页面刷新超时时间
    driver.implicitly_wait(timeout)
    driver.set_page_load_timeout(timeout)
    driver.set_script_timeout(timeout)

    return driver


# 打开指定的URL，定位元素，判断页面是否加载完成,url为TestUrl对象
def test_url(driver, url):
    # 测试数据集
    if driver and url:
        if url.tab is not None:
            switch_window(driver, url.tab)
        request_url = url.url
        script_path = url.script
        if script_path:
            logging.info('执行自定义脚本:' + 'busi.script.' + script_path)
            return execute_script(path='busi.script.' + script_path, driver=driver)
        elif request_url:
            logging.info(f'访问URL=[{request_url}]')
            # 打开页面
            if url.spa:
                begin = time.time()
                get_url(driver, request_url, url.check_element, url.get_cookie_list())
                end = time.time()
                data = PagePerformanceData()
                data.page_load_time = int(round((end - begin) * 1000))
                return data
            else:
                get_url(driver, request_url, url.check_element, url.get_cookie_list())
                return None
        else:
            raise Exception('未配置URL和Script')
    else:
        raise Exception('参数不正确')


def switch_window(driver, tab):
    current_handle = driver.current_window_handle
    handles = driver.window_handles
    if str(tab).isdigit():
        tab = int(tab)
        if tab < 1:
            tab = 1
        if tab > len(handles):
            tab = len(handles)
        driver.switch_to.window(handles[tab - 1])
    else:
        for handle in handles:
            driver.switch_to.window(handle)
            if tab in driver.title or tab in driver.current_url:
                break
            driver.switch_to.window(current_handle)
    logging.info(f'切换到窗口：{tab}')


def get_url(driver, url, check_element, cookie_list):
    driver.get(url)
    if cookie_list and len(cookie_list) > 0:
        driver.delete_all_cookies()
        for cookie in cookie_list:
            driver.add_cookie(cookie)
    if check_element is not None:
        by_type = check_element['by_type']
        by_value = check_element['by_value']
        logging.info(f'检查元素：{by_type}, {by_value}')
        driver.find_element(by_type, by_value)


# 收集性能数据
def collect_pts_data(driver):
    data = PagePerformanceData()
    a = driver
    data.navigation_start = a.execute_script("return performance.timing.navigationStart")
    data.redirect_start = a.execute_script("return performance.timing.redirectStart")
    data.redirect_end = a.execute_script("return performance.timing.redirectEnd")
    data.fetch_start = a.execute_script("return performance.timing.fetchStart")
    data.domain_lookup_start = a.execute_script("return performance.timing.domainLookupStart")
    data.domain_lookup_end = a.execute_script("return performance.timing.domainLookupEnd")
    data.connect_start = a.execute_script("return performance.timing.connectStart")
    data.connect_end = a.execute_script("return performance.timing.connectEnd")
    data.response_start = a.execute_script("return performance.timing.responseStart")
    data.response_end = a.execute_script("return performance.timing.responseEnd")
    data.request_start = a.execute_script("return performance.timing.requestStart")
    data.dom_loading = a.execute_script("return performance.timing.domLoading")
    data.dom_complete = a.execute_script("return performance.timing.domComplete")
    data.dom_interactive = a.execute_script("return performance.timing.domInteractive")
    data.load_event_start = a.execute_script("return performance.timing.loadEventStart")
    data.load_event_end = a.execute_script("return performance.timing.loadEventEnd")
    data.request_info = a.execute_script("return performance.getEntries()")
    data.request_time = data.response_end - data.response_start
    data.redirect_time = data.redirect_end - data.redirect_start
    data.domain_lookup_time = data.domain_lookup_end - data.domain_lookup_start
    data.connect_time = data.connect_end - data.connect_start
    data.dom_render_time = data.dom_complete - data.dom_interactive
    data.blank_screen_time = (data.dom_interactive or data.dom_loading) - data.fetch_start
    data.page_load_time = data.load_event_start - data.fetch_start
    return data
